实验七:Docker-compose 综合训练 完整报告
一、实验目的
- 熟悉 Docker-compose 的基本工作原理;
- 掌握 Docker-compose 安装;
- 熟悉 Docker compose 命令基础;
- 掌握 Docker compose 配置文件。
二、实验环境
- 笔记本直接安装的纯 Linux(Ubuntu)
- Docker 29.7.2
- docker-compose v5.5.0
- 已有 Harbor 环境(占用 80 端口和 172.18.0.0/16 网段)
三、实验步骤
第一部分:安装 docker-compose
检查是否已安装:
bashdocker-compose version
如果没有,用以下命令安装:
bashsudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose
如果 GitHub 下载慢,可以使用代理:
bashsudo curl -L "https://mirror.ghproxy.com/https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose
第二部分:编排 busybox 服务
1. 创建项目目录
bashmkdir -p ~/t1cd ~/t1
2. 创建 docker-compose.yml
bashvim docker-compose.yml
粘贴以下内容:
yamlservices: busybox2: image: busybox:latest container_name: "busybox2" networks: - dev - pro volumes: - /home/we/t1:/data tty: true stdin_open: true command: ["/bin/sh"] busybox3: image: busybox:latest container_name: "busybox3" networks: - pronetworks: dev: driver: bridge pro: driver: bridge
注意:
/home/we/t1换成你自己的家目录,可用echo $HOME查看。
3. 验证配置文件
bashdocker-compose config
4. 启动服务
bashdocker-compose up -d
5. 查看服务状态
bashdocker-compose ps
预期:
busybox2:runningbusybox3:exited (0)(没有 tty,/bin/sh立即退出,正常现象)
6. 验证网络
bashdocker network ls | grep t1
应看到 t1_dev 和 t1_pro 两个网络。
7. 清理
bashdocker-compose down
第三部分:编排 flask + redis 项目(使用 Dockerfile 构建镜像)
1. 创建项目目录
bashmkdir -p ~/t2cd ~/t2
2. 创建 app.py
bashvim app.py
内容:
pythonimport timeimport redisfrom flask import Flaskapp = Flask(__name__)cache = redis.Redis(host='redis', port=6379)def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5)@app.route('/')def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count)
3. 创建 requirements.txt
bashvim requirements.txt
内容:
textflaskredis
4. 创建 Dockerfile(推荐使用 slim 基础镜像)
bashvim Dockerfile
内容:
dockerfileFROM python:3.7-slimWORKDIR /codeENV FLASK_APP app.pyENV FLASK_RUN_HOST 0.0.0.0COPY requirements.txt requirements.txtRUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/COPY . .CMD ["flask", "run"]
重要:如果使用
python:3.7-alpine,需要apk add gcc musl-dev linux-headers安装编译器,国内网络极慢,推荐直接用slim镜像,直接下载预编译 wheel,无需编译。
5. 创建 docker-compose.yml
bashvim docker-compose.yml
内容:
yamlservices: web: build: . ports: - "8080:5000" redis: image: "redis:alpine"
注意:Harbor 已占用 80 端口,所以这里用
8080:5000,避免冲突。
6. 构建并启动
bashdocker-compose up -d --build
7. 查看状态
bashdocker-compose psdocker ps | grep t2
应该看到 t2-web-1 和 t2-redis-1 都在 Up 状态。
8. 访问测试
bashcurl http://localhost:8080
预期输出:
textHello World! I have been seen 1 times.
多执行几次,次数递增,说明 Redis 正常工作。
9. 查看日志(可选)
bashdocker-compose logsdocker-compose logs -f web
10. 清理
bashdocker-compose down# 如需删除镜像docker-compose down --rmi local
四、遇到的问题及解决方法
问题 1:Alpine 镜像中 apk add gcc 极慢
现象:
构建卡在 RUN apk add --no-cache gcc musl-dev linux-headers,运行 20 多分钟未完成。
原因:
Alpine 使用 musl libc,PyPI 上很多包没有对应的预编译 wheel,pip 需要现场用 gcc 编译。而 Alpine 的 apk 源在国内同步慢,gcc 包体积大,下载极慢。
解决:
换用 python:3.7-slim(Debian 基础镜像,使用 glibc)。flask 和 redis 在 glibc 环境有现成的预编译 wheel,无需 gcc,直接 pip install 即可。构建时间从 20+ 分钟降到 20 秒。
dockerfileFROM python:3.7-slim
问题 2:Docker Hub 拉取基础镜像超时
现象:
python:3.7-slim 某一层(约 29MB)拉取 772 秒未完成。
原因:
Docker 守护进程不走系统代理,直接连接 Docker Hub,国内网络慢。
解决:
- 配置国内镜像加速器(daemon.json 中添加
registry-mirrors)。 - 手动执行
docker pull python:3.7-slim提前拉取到本地。 - 避免使用
registry.cn-hangzhou.aliyuncs.com等可能不可用的第三方镜像源。
问题 3:docker-compose up -d 不重新构建镜像
现象:
修改了 Dockerfile(例如修正 CMD),执行 docker-compose up -d 后容器仍然报错,COMMAND 显示还是旧命令。
原因:
docker-compose up -d 默认复用旧镜像,不会自动重新构建。
解决:
必须加上 --build 参数:
bashdocker-compose up -d --build
问题 4:CMD 写法错误导致容器无法启动
现象:
日志显示 /bin/sh: 1: [flask,: not found,容器启动后秒退。
原因:
Dockerfile 中 CMD 没有用引号包裹,或者格式不对,导致 Docker 把它当成 shell 命令执行。
解决:
使用正确的 exec 格式:
dockerfileCMD ["flask", "run"]
问题 5:80 端口被 Harbor 占用
现象:
实验文档中 flask 映射端口为 "80:5000",但启动后无法访问。
原因:
实验四搭建的 Harbor 中的 nginx 容器已经占用了宿主机的 80 端口(0.0.0.0:80->8080/tcp)。
解决:
修改 docker-compose.yml,将端口映射改为 "8080:5000":
yamlports: - "8080:5000"
访问时使用 http://localhost:8080。
问题 6:app.py 代码包含 OCR 转义符号导致语法错误
现象:
容器启动后日志报 SyntaxError,指向 app.py 中奇怪的符号(如 \(\coloneqq\))。
原因:
实验文档中的 app.py 代码是从图片 OCR 识别出来的,包含大量非 Python 语法的符号。
解决:
手动重写 app.py,确保使用标准 Python 语法,尤其是 redis.Redis(host='redis', port=6379) 这一行。
问题 7:version 属性已过时警告
现象:
每次执行 docker-compose 命令都出现 WARN[0000] the attribute version is obsolete。
原因:
新版 docker-compose 不再需要 version 字段。
解决:
删除 docker-compose.yml 中的 version: '3' 行即可,不影响功能。
五、证明实验完成的命令
bash# 1. 安装验证docker-compose version# 2. busybox 编排cd ~/t1docker-compose up -ddocker-compose psdocker network ls | grep t1docker-compose down# 3. flask + redis 编排cd ~/t2docker-compose up -d --builddocker-compose pscurl http://localhost:8080curl http://localhost:8080curl http://localhost:8080docker-compose logsdocker-compose down
六、实验总结
docker-compose通过docker-compose.yml文件批量管理多个容器,适合多服务项目。version字段已过时,新版可省略。docker-compose up -d默认复用旧镜像,修改 Dockerfile 后需加--build重新构建。CMD必须用 exec 格式(带引号),否则会解析错误。- 国内构建 Python 项目时,推荐使用
python:3.x-slim基础镜像,避免 Alpine 的 apk 和源码编译问题。 - pip 使用国内源(阿里云、清华)可以大幅加速依赖安装。
- Docker 守护进程不走系统代理,需要配置
registry-mirrors或者手动docker pull基础镜像。 - 端口映射要避开已有服务(如 Harbor 的 80 端口),可以用 8080 等替代。
实验七完成。



